const CFG = require('./config');
const FUN = require('./comm/func');
const tbDevice = require('./model/tb_device');
const mqttConn = require('./utils/mqttConn');
const DevManger = require('./utils/devManger');
const {CombTopic} = require('./utils/devConfig');

// 本程序，会订阅api服务器上的mq主题，所以可以处理到实际在线设备的请求，并发包出去
// 但如果本程序运行在调试环境，发包必然会和生产环境的程序相冲突，形成重复回包, 所以本地调试禁止往外发包

// 检测是不是本地运行
if (FUN.isLocal()) {
  console.log("\n\nIs Local Host:", require("os").hostname());
} else {
  console.log("\n\nIs Remote Srv:", require("os").hostname());
}

// 启动websocket服务器
require('./utils/webSocket');

//初始化db和reids
tbDevice.offlineAllDev().then((affectNum)=>{
  console.log('Init Dev', affectNum);
  DevManger.Init(); // 初始化redis的config节点
})

FUN.SleepMs(2000); // 延时两秒等mqtt服务器启动完成

// 启动一个mqtt链接对象，供设备管理使用
mqttConn.newClient('admin.1'+FUN.rand(12345678,99999999), devConfigConnCb);

// 启动一个mqtt链接对象，供前台websocket设备使用
mqttConn.newClient('admin.2'+FUN.rand(12345678,99999999), webSrcConnCb);

// 连接回调
function devConfigConnCb(conn)
{
  let devConfig = require('./utils/devConfig');
  let Topics = [];

  //订阅主题
  for (let type of [CFG.T_Wpass, CFG.T_Gw, CFG.T_Wdev]) {
    Topics.push(CombTopic('cmdres', '+'+type));
    Topics.push(CombTopic('json', '+'+type));
  }
  Topics.push(CombTopic('online','+'));
  Topics.push(CombTopic('offline','+'));
  Topics.push('srv/debug');
  console.log('[Sub Topic]', Topics.join(', '));

  conn.msgHdrs = [];
  conn.msgHdrs.push(devConfig); // 注册回调app
  devConfig.mqConn = conn;
  devConfig.mqPub = function(topic, payload, opts={retain:false}) {//mqtt发包函数
    if (FUN.isLocal()) {console.log('N>>', topic, payload); return;}//防止本地调试时，对在线设备重复发包
    conn.publish(topic, payload, opts);
    if (!opts.nolog) console.log('>>>', topic, payload);
  }
  conn.subscribe(Topics, (err)=>{if(err)console.log('err2:',err)});
}

// 连接回调
function webSrcConnCb(conn)
{
  const webDevManger = require('./utils/webDevManger');
  let Topics = [];

  // 订阅主题
  for (let type of [CFG.T_Wpass, CFG.T_Gw, CFG.T_Wdev, CFG.T_Dtu]) {
    Topics.push(CombTopic('cmdres', '+'+type));
    Topics.push(CombTopic('json', '+'+type));
    Topics.push(CombTopic('log', '+'+type));
    Topics.push(CombTopic('tx', '+'+type, '+'));
    Topics.push(CombTopic('rx', '+'+type, '+'));
    Topics.push(CombTopic('var', '+'+type, '+'));
    Topics.push(CombTopic('data', '+'+type, '+'));
  }
  Topics.push('srv/debug');
  console.log('[Sub Topic]', Topics.join(', '));

  conn.msgHdrs = [];
  conn.msgHdrs.push(webDevManger);
  webDevManger.mqConn = conn;
  webDevManger.mqPub = function(topic, payload, opts={retain:false}) { // mqtt发包函数
    if (FUN.isLocal()) {console.log('N>>', topic, payload); return;} // 防止本地调试时，对在线设备重复发包
    conn.publish(topic, payload, opts);
    if (!opts.nolog) console.log('W>>', topic, payload);
  }
  conn.subscribe(Topics, (err)=>{if(err)console.log('err3:',err)});
}

// const shareEvt = require('events').EventEmitter;
// global.shareEvt = new shareEvt(); // 定义公共事件主体

// 监听mq断开事件
// global.shareEvt.on('mqtt_close', (clientId, callback)=>{
//   console.log(clientId);
//   setTimeout(()=>{
//     mqttConn.newClient(clientId, callback);
//   },5000); // 延时一段时间再重连
// })